<template>
  <div class="permission-con clearfix" v-loading="showEditLoading">
    <div class="left fl">
      <a-scrollbar style="height: calc(100vh - 291px); overflow: auto; margin-top: 40px">
        <div class="menu-con">
          <a-anchor line-less :change-hash="false" style="width: 100%; height: calc(100vh - 291px)" v-if="treeList[0]">
            <a-anchor-link :class="[index == currentIndex ? 'active' : '']" :href="'#' + item.id" v-for="(item, index) of treeList" @click="selPreDetail(item, index)"> {{ item.menuName }} </a-anchor-link>
          </a-anchor>
          <a-empty v-else />
        </div>
      </a-scrollbar>
    </div>
    <div class="right fl">
      <div class="top">
        <div class="checkbox-all">
          <a-checkbox v-model="selectAllBtn" @change="handleSelectAll">全选</a-checkbox>
        </div>
        <div class="btn">
          <a-button class="gray-outline mr10" @click="reset">重置</a-button>
          <a-button type="primary" :loading="submitLoading" @click="handleOk">保存</a-button>
        </div>
      </div>
      <div style="border: 1px solid #d7d7d7; padding: 5px">
        <a-scrollbar v-if="treeList[0]" style="height: calc(100vh - 310px); overflow: auto">
          <div class="per-con">
            <div class="item" v-for="item of treeList">
              <div :id="item.id">
                <a-checkbox @change="handleSelectItemAll($event, userSelResArr[item.id], item)" v-model:model-value="userSelResArr[item.id].checkedAll" :indeterminate="userSelResArr[item.id].indeterminate">{{ item.menuName }} </a-checkbox>
              </div>
              <div class="con" v-for="children of item.children">
                <div class="per-page">
                  <a-checkbox v-model="userSelResArr[item.id][children.menuUrl].isSelMenu" @change="handleChange">{{ children.menuName }}</a-checkbox>
                  <br />
                  <a-button type="text" :disabled="!userSelResArr[item.id][children.menuUrl].isSelMenu" @click="setDatePermission(children)">数据范围</a-button>
                </div>
                <div class="per-btn">
                  <div style="width: 100px" v-if="children.funcList.length > 0">
                    <a-checkbox :disabled="!userSelResArr[item.id][children.menuUrl].isSelMenu" @change="selAllCode($event, children.funcList, userSelResArr[item.id][children.menuUrl])">全选</a-checkbox>
                  </div>
                  <div style="flex: 1">
                    <a-checkbox-group background-color="#fff" v-model="userSelResArr[item.id][children.menuUrl].funcCodeList" @change="handleChange">
                      <!-- <a-checkbox :value="lastChildren.funcCode" v-for="lastChildren of children.funcList">{{ lastChildren.funcName }} -- {{ lastChildren.funcCode }}</a-checkbox> -->

                      <a-popover v-for="lastChildren of children.funcList">
                        <a-checkbox :value="lastChildren.funcCode" :disabled="!userSelResArr[item.id][children.menuUrl].isSelMenu">{{ lastChildren.funcName }}</a-checkbox>
                        <template #content>
                          <div>{{ lastChildren.funcCode }}</div>
                        </template>
                      </a-popover>
                    </a-checkbox-group>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </a-scrollbar>
        <a-empty v-else />
      </div>
    </div>
  </div>
  <DataField ref="dataField" :info="dataFieldInfo" :permissionList="userOwenPer" :roleId="roleId" :ownId="userOwenPer.id" :getPermissionTreeList="getPermissionTreeList" />
</template>

<script lang="ts">
  import { toRefs } from '@vueuse/core'
  import { defineComponent, ref, reactive, watch, provide } from 'vue'
  import { listMenuFuncs, getFuncPermisson, saveOrUpdateFuncPermisson } from '@/api/system'
  import { Message, Modal } from '@arco-design/web-vue'
  import DataField from './dataField/index.vue'
  import _ from 'lodash-es'
  export default defineComponent({
    components: { DataField },
    props: ['roleId'],
    setup(props: any, { emit }) {
      const dataField = ref()
      const data: any = reactive({
        currentIndex: 0,
        userSelResArr: {},
        treeList: [],
        rightList: [],
        selectAllBtn: false,
        submitLoading: false,
        userOwenPer: {},
        dataFieldInfo: {},
        showEditLoading: false,
      })

      const getPermissionTreeList = async () => {
        const res: any = await listMenuFuncs()
        data.treeList = res?.data || []
        initData()
        // 查询用户已有的权限数据
        getUserPersion(props.roleId)
      }
      getPermissionTreeList()

      const initData = () => {
        // data.userSelResArr = []
        data.treeList.forEach((e: any) => {
          data.userSelResArr[e.id] = {}
          data.userSelResArr[e.id].indeterminate = false
          data.userSelResArr[e.id].checkedAll = false
          e.children.forEach((el: any) => {
            // data.userSelResArr[e.id].permissionArr = []
            let obj = {
              dataPermisson: {},
              funcCodeList: [],
              menuUrl: el.menuUrl,
              firstMenuId: e.id,
              isSelMenu: false,
            }
            data.userSelResArr[e.id][el.menuUrl] = obj
          })
        })
      }

      const getUserPersion = async (id: string) => {
        data.showEditLoading = true
        let params = {
          roleId: id,
        }
        try {
          const res: any = await getFuncPermisson(params)
          data.userOwenPer = res?.data || {}
          let menuList = res?.data?.menuList || []
          if (menuList[0]) {
            menuList.forEach((e: any) => {
              // 获取到当前URL下面的所有codelist
              let funccodeList: any = []
              data.treeList.forEach((el: any) => {
                let item = el.children.find((ell: any) => ell.menuUrl == e.menuUrl)
                if (item) funccodeList = item.funcList
              })

              // 和选中的code作对比，分两种情况：全选和半选
              if (e.funcCodeList.length > 0 && e.funcCodeList.length < funccodeList.length) {
                e.checkedCodeAll = false
                e.codeIndeterminate = true
              } else if (e.funcCodeList.length == funccodeList.length) {
                e.codeIndeterminate = false
                e.checkedCodeAll = true
              }
              e.isSelMenu = true
              data.userSelResArr[e.firstMenuId][e.menuUrl] = e
            })
            echo()
          } else {
            initData()
          }
        } catch (error) {}
        data.showEditLoading = false
      }

      const echo = () => {
        let allNumObj = {}
        data.treeList.forEach((e: any) => {
          let num = 0
          e.children.forEach((el: any) => {
            num += 1
            num += el.funcList.length
          })
          allNumObj[e.id] = num
        })

        for (const key in data.userSelResArr) {
          let num = 0
          for (const subKey in data.userSelResArr[key]) {
            if (typeof data.userSelResArr[key][subKey] != 'boolean') {
              for (const childrenKey in data.userSelResArr[key][subKey]) {
                if (childrenKey == 'funcCodeList' && data.userSelResArr[key][subKey][childrenKey] instanceof Array) {
                  num += data.userSelResArr[key][subKey][childrenKey].length
                } else if (childrenKey == 'isSelMenu' && data.userSelResArr[key][subKey][childrenKey]) {
                  num += 1
                }
              }
            }
          }
          if (num > 0) {
            if (num < allNumObj[key]) {
              data.userSelResArr[key].indeterminate = true
              data.userSelResArr[key].checkedAll = false
            } else if (num == allNumObj[key]) {
              data.userSelResArr[key].indeterminate = false
              data.userSelResArr[key].checkedAll = true
            } else {
              data.userSelResArr[key].indeterminate = false
              data.userSelResArr[key].checkedAll = false
            }
          } else {
            data.userSelResArr[key].indeterminate = false
            data.userSelResArr[key].checkedAll = false
          }
        }
      }

      const handleChange = () => {
        echo()
      }

      const handleSelectItemAll = (val: boolean, userSelItem: any, treeItem: any) => {
        if (val) {
          for (const key in userSelItem) {
            if (typeof userSelItem[key] != 'boolean') {
              treeItem.children.forEach((e: any) => {
                if (key == e.menuUrl) {
                  userSelItem[key].isSelMenu = true
                  userSelItem[key].funcCodeList = e.funcList.map((el: any) => el.funcCode)
                }
              })
            }
          }
        } else {
          for (const key in userSelItem) {
            if (typeof userSelItem[key] != 'boolean') {
              userSelItem[key].isSelMenu = false
              userSelItem[key].funcCodeList = []
            }
          }
        }
        echo()
      }

      const handleSelectAll = (val: boolean) => {
        for (const key in data.userSelResArr) {
          let item: any = data.treeList.find((e: any) => e.id == key)
          handleSelectItemAll(val, data.userSelResArr[key], item)
        }
      }

      const selPreDetail = (item: any, index: number) => {
        data.currentIndex = index
      }

      const reset = () => {
        Modal.error({
          title: '提示',
          content: '重置之后将清空已选的功能权限，是否重置？',
          titleAlign: 'start',
          hideCancel: false,
          onOk: () => {
            data.selectAllBtn = false
            // handleSelectAll(false)
            getPermissionTreeList()
          },
        })
      }

      const handleOk = async () => {
        let params: any = {
          id: data.userOwenPer ? data.userOwenPer.id : '',
          roleId: props.roleId,
          menuList: [],
        }
        let arr = []

        for (const key in data.userSelResArr) {
          for (const subKey in data.userSelResArr[key]) {
            if (typeof data.userSelResArr[key][subKey] != 'boolean') {
              let obj = _.cloneDeep(data.userSelResArr[key][subKey])
              if (!obj.isSelMenu) {
                obj.menuUrl = ''
              }
              arr.push(obj)
            }
          }
        }
        params.menuList = arr.filter((e: any) => e.menuUrl)
        try {
          data.submitLoading = true
          const res: any = await saveOrUpdateFuncPermisson([params])
          Message.success('功能权限保存成功')
          getUserPersion(props.roleId)
          data.submitLoading = false
        } catch (error) {
          data.submitLoading = false
        }
      }

      const setDatePermission = (item: any) => {
        data.dataFieldInfo = item
        dataField.value.visible = true
      }

      const isSaveMenuUrl = (item: any) => {
        let perList = data?.userOwenPer?.menuList || []
        let index = perList.findIndex((e: any) => e.menuUrl == item.menuUrl)
        return index == -1 ? true : false
      }

      const selAllCode = (val: boolean, list: any, obj: any) => {
        val ? (obj.funcCodeList = list.map((e: any) => e.funcCode)) : (obj.funcCodeList = [])
      }

      return {
        ...(toRefs(data) as any),
        selPreDetail,
        getUserPersion,
        getPermissionTreeList,
        echo,
        handleChange,
        handleSelectItemAll,
        handleSelectAll,
        reset,
        handleOk,
        setDatePermission,
        dataField,
        isSaveMenuUrl,
        selAllCode,
      }
    },
  })
</script>

<style lang="less" scoped>
  :deep(.arco-anchor-link) {
    display: inline-block;
    width: 100%;
    height: 40px;
    padding: 0;
    padding-left: 10px;
    padding-top: 10px;
    // background-color: none;
  }

  // :deep(.arco-anchor-line-less .arco-anchor-link-active > .arco-anchor-link) {
  //   color: black;
  // }

  // :deep(.arco-anchor-link:hover) {
  //   background-color: white;
  // }

  .permission-con {
    padding: 10px;
    box-sizing: border-box;
    .left {
      width: 200px;
      .menu-con {
        width: 100%;

        ul {
          li {
            border-left: 4px solid #f2f2f2;
            height: 40px;
            // padding: 10px;
            margin-bottom: 5px;
            cursor: pointer;
            user-select: none;
          }
          .active {
            background-color: #f2f2f2 !important;
            border-left: 4px solid #165dff !important;
          }
        }
      }
    }
    .right {
      width: calc(100% - 205px);
      margin-left: 5px;
      .top {
        display: flex;
        justify-content: space-between;
        align-items: center;
        height: 40px;
      }
    }

    .per-con {
      :deep(.arco-checkbox-group) {
        width: 100%;
      }

      .item {
        width: 100%;
        // height: 81000px;
        margin-bottom: 30px;
        .con {
          width: 100%;
          min-height: 140px;
          border-top: 1px solid #d7d7d7;
          border-left: 1px solid #d7d7d7;
          border-right: 1px solid #d7d7d7;
          // border-bottom: none;
          display: flex;

          &:last-child {
            border-bottom: 1px solid #d7d7d7;
          }

          .per-page {
            width: 200px;
            border-right: 1px solid #d7d7d7;
            padding: 5px;
          }
          .per-btn {
            flex: 1;
            display: flex;
            padding: 5px;
            :deep(.arco-checkbox) {
              display: inline-block;
              min-width: 260px;
            }
          }
        }
      }
    }
  }
</style>
